<script setup lang="ts">
import YkPagination from '@yk/components/pagination/YkPagination.vue'
import { Pages } from '@typings/pages'
import { Plus } from '@element-plus/icons-vue'
import YkTableColumn from '@yk/components/table-column/YkTableColumn.vue'
import { ObjectUtil } from '@utils/object-util'
import { ElForm, ElTable } from 'element-plus'
import YkDatePicker from '@yk/components/date-picker/YkDatePicker.vue'
import { SceneDTO, SceneSaveForm } from '@/api/entity/scene'
import { required } from '@utils/form-rule'
import { addSceneAPI, delSceneAPI, editSceneAPI, getSceneListByPageAPI, sceneSortAPI } from '@/api/scene'
import { DeviceDTO } from '@/api/entity/device'
import { ref } from 'vue'
import { getSelfBySceneIdAPI } from '@/api/self-config'
import { getEncryptVStr } from '@/router/interceptor/security'
import { checkDeviceNameRepeatAPI, getDeviceListAPI } from '@/api/device'
import { FileUtil, MountedCheck } from '@/utils'
import ShowDrawC from '@views/self-config/components/ShowDraw.vue'
import YkAdaptiveBox from '@yk/components/adaptive-box/YkAdaptiveBox.vue'
import YkEmptyBox from '@yk/components/empty-box/YkEmptyBox.vue'
import { EmptyEnum, EmptyState, EmptyType } from '@yk/components/empty-box/type'
import lodash from '@utils/lodash'

const router = useRouter()

defineOptions({ name: 'SceneManage' })

const mc = new MountedCheck()
onMounted(() => {
  searchHandle()
  mc.end()
})

onActivated(() => {
  if (mc.isMounted()) return
  tableDataRef.value.doLayout()
  // getTableData()
})

// this.car_enter_color.forEach(item => {
//   if (form[item.key] == 0) {
//     this.formData.is_enter_color.push(item.value)
//   }
// })

// // 建立字典
// const carDic = this.car_enter_color.reduce((ret, item) => {
//   form[item.key] = 0
//   ret[item.value] = item
//   return ret
// }, {})
//
// this.formData.is_enter_color.forEach(val => {
//   form[carDic[val].key] = 1
// })

// region TODO 查询
const searchParams = reactive({
  q: '',
  startTime: '',
  endTime: ''
})
function searchHandle () {
  pages.pageNum = 1
  getTableData()
}
// endregion

// region TODO 表格数据
const pages = reactive(new Pages())
const tableData = shallowRef<SceneDTO[]>([])
const tableDataRef = shallowRef<InstanceType<typeof ElTable>>()
function getTableData () {
  const loading = ElLoading.service()
  getSceneListByPageAPI({
    ...pages.getParams(),
    param: searchParams
  }).then((res) => {
    res.result().then((rdata) => {
      currentSelectRow.value = null
      previewSelfId.value = null
      tableData.value = rdata.records
      pages.total = rdata.total
    })
  }).finally(loading.close)
}
function delTableItem (id: string) {
  ElMessageBox.confirm('删除当前场景？', '删除提醒').then(() => {
    delSceneAPI({ id }).then((res) => {
      res.result().then(() => {
        getTableData()
      })
    })
  })
}
const currentSelectRow = shallowRef<SceneDTO>()
// 点击表格行事件
function tableDataRowClick (e: SceneDTO) {
  currentSelectRow.value = e
  previewSelf(e.id)
}
// endregion

// region TODO 添加/修改表单
const saveForm = ref(new SceneSaveForm())
// 设备ids
const saveDeviceIds = ref<string[]>([])
const saveFormRules = {
  // 场景名称
  name: [required('场景名称为必填项')]
}
const saveFormRef = shallowRef<InstanceType<typeof ElForm>>()
function submitSaveForm () {
  saveFormRef.value.validate().then(() => {
    const loading = ElLoading.service()
    const params = ObjectUtil.copy(saveForm.value)
    // 记录当前的排序
    const sortDic = params.deviceDTOList.reduce<Record<string, number>>((ret, item) => {
      ret[item.id] = item.sort
      return ret
    }, {})

    params.deviceDTOList = ObjectUtil.copy(deviceList.value.filter(item => saveDeviceIds.value.includes(item.id)))

    // 给老设备添加曾经的排序
    let list1 = []
    const list2 = []
    params.deviceDTOList.forEach((item) => {
      if (ObjectUtil.isNotEmpty(sortDic[item.id])) {
        item.sort = sortDic[item.id]
        list1.push(item)
      } else {
        list2.push(item)
      }
    })

    list1 = list1.sort((a, b) => {
      return a.sort - b.sort
    })
    params.deviceDTOList = [...list1, ...list2]
    console.log(params.deviceDTOList)

    const result = saveForm.value.id ? editSceneAPI(params) : addSceneAPI(params)
    result.then((res) => {
      res.result().then(() => {
        ElMessage.success('保存成功')
        closeSaveFormDialog()
        getTableData()
      })
    }).finally(loading.close)
  })
}

// region TODO 设备列表
const deviceList = shallowRef<DeviceDTO[]>(null)
function getDeviceList () {
  getDeviceListAPI().then((res) => {
    res.result().then((rdata) => {
      deviceList.value = rdata.data
      updateShowDeviceList()
    })
  })
}
// endregion

// region TODO 对话框
const saveFormDialogModel = ref(false)
function showSaveFormDialog (item?: SceneDTO) {
  saveFormDialogModel.value = true
  getDeviceList()
  if (item) {
    nextTick(() => {
      ObjectUtil.updateVal(saveForm.value, item)
      saveDeviceIds.value = saveForm.value.deviceDTOList.map(item => item.id)
    })
  }
}
function closeSaveFormDialog () {
  saveFormRef.value.resetFields()
  saveForm.value.id = null
  saveDeviceIds.value = []
  saveFormDialogModel.value = false
}

// endregion

// region TODO 搜索
const showDeviceList = shallowRef<DeviceDTO[]>([])
const deviceListSearch = ref('')
watch(deviceListSearch, () => {
  updateShowDeviceList()
})
function updateShowDeviceList () {
  if (deviceListSearch.value) {
    showDeviceList.value = deviceList.value.filter((item) => {
      return item.deviceName.includes(deviceListSearch.value)
    })
  } else {
    showDeviceList.value = deviceList.value
  }
}
// endregion

// region TODO 全选
const checkAllDeviceList = ref(false)
const isCheckAll = computed(() => {
  let ret = true
  for (let i = 0, len = showDeviceList.value.length; i < len; i++) {
    if (!saveDeviceIds.value.includes(showDeviceList.value[i].id)) {
      ret = false
      break
    }
  }
  return ret
})
watch(isCheckAll, (nv) => {
  checkAllDeviceList.value = nv
})
function checkAllChangeHandle (res: boolean) {
  const ids = showDeviceList.value.map(item => item.id)
  if (res) { // 全选
    const checkIds = saveDeviceIds.value.concat(ids)
    saveDeviceIds.value = Array.from(new Set(checkIds).values())
  } else { // 全不选
    const checkIds = new Set(saveDeviceIds.value)
    for (let i = 0, len = ids.length; i < len; i++) {
      checkIds.delete(ids[i])
    }
    saveDeviceIds.value = Array.from(new Set(checkIds).values())
  }
}
// endregion

// endregion

// region TODO 跳转
function toVideoView () {
  router.push({ name: 'VideoIndex' })
}
// 组态
function toSelf (id: string) {
  getSelfBySceneIdAPI({ id }).then((res) => {
    res.result().then((rdata) => {
      const data = rdata.data || []
      const self = data[0]
      if (self?.id) {
        window.open('/#/show-draw?v=' + getEncryptVStr({ query: { id: self.id } }), '_blank')
      } else {
        ElMessageBox.alert('该场景未配置组态，是否前往组态页面添加？', '提醒', {
          confirmButtonText: '前往'
        }).then(() => {
          router.push({ name: 'SelfConfigManage' })
        })
      }
    })
  })
}

// 设备数据
function toDeviceData (id: string) {
  router.push({ name: 'DeviceData', query: { id } })
}
// endregion

// region TODO 设备排序
// 当前场景
const currentSortScene = shallowRef<SceneDTO>()
// 场景中需要排序的设备列表
const deviceSortList = ref<DeviceDTO[]>([])
// 对话框是否弹起
const deviceSortDialogModel = ref(false)
// 弹起对话框
function showDeviceSortDialog (scene: SceneDTO) {
  deviceSortDialogModel.value = true
  currentSortScene.value = scene
  deviceSortList.value = ObjectUtil.copy(scene.deviceDTOList)
  updateSortTempData()
}
// 关闭对话框
function closeDeviceSortDialog () {
  deviceSortDialogModel.value = false
  currentSortScene.value = null
  deviceSortList.value = []
  sortTempData.value = []
}
// 排序序号
const sortTempData = ref([])
watch(() => deviceSortList.value.length, () => {
  deviceSortDialogModel.value && updateSortTempData()
}, { deep: false })
function updateSortTempData () {
  const len = deviceSortList.value.length
  const temp = []
  for (let i = 0; i < len; i++) {
    temp[i] = i + 1
  }
  nextTick(() => {
    sortTempData.value = temp
  })
}

function sortBlurHandle (index: number) {
  const tableItem = deviceSortList.value.splice(index, 1)
  deviceSortList.value.splice(sortTempData.value[index] - 1, 0, ...tableItem)
  updateSortTempData()
}

function deviceSortSubmit () {
  const loading = ElLoading.service()
  sceneSortAPI({
    id: currentSortScene.value.id,
    deviceDTOList: deviceSortList.value
  }).then((res) => {
    res.result().then(() => {
      ElMessage.success('保存成功')
      currentSortScene.value.deviceDTOList = deviceSortList.value
      closeDeviceSortDialog()
    })
  }).finally(loading.close)
}
// endregion

// region TODO 组态预览
const previewSelfId = shallowRef(null)
const adaptiveBoxRef = shallowRef()
const adaptiveReferenceRef = shallowRef<HTMLDivElement>()
function selfLoadHandle () {
  adaptiveBoxRef.value.resize()
}
const previewSelfIdDefaultState = { type: EmptyEnum.EMPTY_VAR, description: '请选择一个场景预览组态画面' }
const previewSelfIdState = shallowRef<EmptyState>(previewSelfIdDefaultState)
// 预览组态
const previewSelf = lodash.debounce((sceneId: string) => {
  previewSelfId.value = null
  previewSelfIdState.value = EmptyEnum.LOADING
  const catchFn = () => (previewSelfIdState.value = { type: EmptyEnum.EMPTY_TIP, description: '获取数据异常，请稍后重试' })
  getSelfBySceneIdAPI({ id: sceneId }).then((res) => {
    res.result().then((rdata) => {
      const data = rdata.data || []
      const self = data[0]
      if (self?.id) {
        previewSelfId.value = self.id
        previewSelfIdState.value = EmptyEnum.SUCCESS
      } else {
        previewSelfIdState.value = { type: EmptyEnum.EMPTY, description: '该场景未配置组态，您可以前往组态页面添加' }
      }
    }).catch(catchFn)
  }).catch(catchFn)
})

// endregion
</script>

<template>
  <div class="layout_view d-flex" style="min-height: 100%;">
    <div class="c_card-page w-100">
      <div class="c_card_header c_card-title bor-divider-b">场景配置</div>
      <!--搜索表单-->
      <el-form inline class="c_form-search pt-16" @submit.prevent="searchHandle">
        <el-form-item label="场景名称：">
          <el-input v-model="searchParams.q" placeholder="请输入场景名称搜索" />
        </el-form-item>
        <el-form-item>
          <yk-date-picker
            v-model:start="searchParams.startTime" v-model:end="searchParams.endTime"
            value-format="YYYY-MM-DD HH:mm:ss" type="daterange" clearable
          />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="searchHandle">查询</el-button>
        </el-form-item>
      </el-form>
      <!--功能栏-->
      <div class="d-flex-between">
        <el-button type="primary" :icon="Plus as any" @click="showSaveFormDialog()">添加场景</el-button>
        <!--<el-button class="c_btn&#45;&#45;export debugger-bor" :icon="Download as any" @click="exportTableData">导出</el-button>-->
      </div>
      <div class="mt-16 d-flex" style="height: calc(100% - 140px);min-height: fit-content;">
        <!--表格-->
        <div class="">
          <!--表格-->
          <el-table
            ref="tableDataRef"
            class="c_table-page" style="width: 550px;" stripe
            :data="tableData" current-row-key="id" highlight-current-row
            @row-click="tableDataRowClick"
          >
            <el-table-column label="#" type="expand">
              <template #default="scope">
                <div v-if="scope.row.deviceDTOList.length" class="table__device-list px-20 py-16 d-grid text-color-primary fs-14">
                  <span v-for="(item, index) in scope.row.deviceDTOList" :key="item">设备{{ index + 1 }}：
                    <el-link type="primary" @click="toDeviceData(item.id)">{{ item.deviceName }}</el-link>
                  </span>
                </div>
                <div v-else class="text-center w-100 text-color-placeholder">暂无关联设备</div>
              </template>
            </el-table-column>
            <yk-table-column label="场景名称" prop="name" />
            <!--<yk-table-column label="关联设备" prop="" />-->
            <yk-table-column label="添加时间" prop="createdAt" sortable />
            <el-table-column label="操作" width="140px">
              <template #default="scope">
                <div class="c_table-operation d-flex align-items-center" @click.stop>
                  <el-link type="primary" size="small" @click="showSaveFormDialog(scope.row)">编辑</el-link>
                  <el-dropdown>
                    <el-link class="ml-3" type="primary" size="small">更多</el-link>
                    <!--<el-avatar :src="FileUtil.prefixImage(appStore.userInfo.avatar, FileUtil.DefaultImage.Avatar)" class="ml-24" :size="32" />-->
                    <template #dropdown>
                      <el-dropdown-menu>
                        <el-dropdown-item @click="showDeviceSortDialog(scope.row)">设备排序</el-dropdown-item>
                        <el-dropdown-item @click="toVideoView">摄像头</el-dropdown-item>
                        <el-dropdown-item @click="toSelf(scope.row.id)">组态</el-dropdown-item>
                        <el-dropdown-item class="color-danger" @click="delTableItem(scope.row.id)">删除</el-dropdown-item>
                      </el-dropdown-menu>
                    </template>
                  </el-dropdown>
                </div>
              </template>
            </el-table-column>
          </el-table>
          <!--分页-->
          <el-affix target=".c_table-page" position="bottom" :offset="0">
            <yk-pagination class="c_table-pagination-page" :pages="pages" @handle="getTableData" />
          </el-affix>
        </div>
        <div class="bor-info-light-3 ml-3 flex-1 position-relative" style="border-width: 3px;">
          <div ref="adaptiveReferenceRef" class="position-absolute wh-100">
            <yk-empty-box :state="currentSelectRow ? previewSelfIdState : previewSelfIdDefaultState" class="wh-100">
              <yk-adaptive-box
                v-if="adaptiveReferenceRef" ref="adaptiveBoxRef" class=""
                :reference="adaptiveReferenceRef"
                mode="contain"
              >
                <show-draw-c v-if="previewSelfId" :self-id="previewSelfId" @load="selfLoadHandle" />
              </yk-adaptive-box>
              <template #footer="{ type }">
                <el-button v-if="type === 'Empty'" type="primary" @click="router.push({ name: 'SelfConfigManage' })">前往添加</el-button>
              </template>
            </yk-empty-box>
          </div>
        </div>
      </div>
    </div>
    <!--添加/修改表单-->
    <el-dialog
      v-model="saveFormDialogModel" :title="saveForm.id ? '编辑场景' : '添加场景'" width="545px"
      :close-on-click-modal="false" draggable :modal="false"
      @close="closeSaveFormDialog"
    >
      <el-form
        ref="saveFormRef" class="mt-20" :model="saveForm"
        :rules="saveFormRules"
        label-width="120px"
      >
        <el-form-item label="场景名称：" prop="name">
          <el-input
            v-model.trim="saveForm.name" placeholder="请输入场景名称" :maxlength="12"
            show-word-limit
            style="width: 262px"
          />
        </el-form-item>
        <el-form-item label="关联设备：">
          <div class="bor-divider p-16 d-flex flex-column" style="width: 262px;">
            <!--搜索框-->
            <div class="d-flex-between-center">
              <el-input v-model="deviceListSearch" placeholder="请输入设备名称搜索" style="--el-input-border-radius: 15px;width: 160px;" />
              <el-checkbox v-model="checkAllDeviceList" label="全选" @change="checkAllChangeHandle" />
            </div>
            <!--设备列表-->
            <div class="overflow-auto mt-16" style="max-height: calc(100vh - 600px);min-height: 100px;">
              <el-checkbox-group v-model="saveDeviceIds">
                <el-checkbox v-for="item in showDeviceList" :key="item.id" :label="item.id" class="d-block">{{ item.deviceName }}</el-checkbox>
              </el-checkbox-group>
              <div v-if="!deviceList?.length" class="c_form-tip text-center">暂无可用设备</div>
            </div>
          </div>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="c_form__submit-btn">
          <el-button type="primary" plain @click="closeSaveFormDialog">取消</el-button>
          <el-button type="primary" @click="submitSaveForm">确定</el-button>
        </div>
      </template>
    </el-dialog>
    <!--设备排序-->
    <el-dialog
      v-model="deviceSortDialogModel" title="设备排序" draggable
      width="450" :close-on-click-modal="false" @close="closeDeviceSortDialog"
    >
      <el-table :data="deviceSortList" max-height="400px">
        <el-table-column type="index" label="#" />
        <el-table-column label="排序" width="80">
          <template #default="{ $index }">
            <el-input-number
              v-model="sortTempData[$index]"
              size="small" class="el-c-input-pure w-100" :step="1"
              :min="1" @keyup.enter="sortBlurHandle($index)"
              @blur="sortBlurHandle($index)"
            />
          </template>
        </el-table-column>
        <el-table-column label="设备名称" prop="deviceName" />
      </el-table>
      <template #footer>
        <div class="c_form__submit-btn">
          <el-button type="primary" plain @click="closeDeviceSortDialog">取消</el-button>
          <el-button type="primary" @click="deviceSortSubmit">确定</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped lang="scss">
::v-deep(.el-table) {
  .el-table__body tr.current-row > td.el-table__cell {
    background-color: var(--el-table-current-row-bg-color) !important;
  }
}
// 表格 - 设备列表
.table__device-list {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  grid-gap: 16px;
}
</style>
